
let currentEffect

// 副作用参数可选参
interface Options {
    lazy?: boolean // 是否懒执行
    scheduler?: Function // 调度函数
}
// 副作用函数 响应式数据变化时触发副作用函数
export const effect = (fn: Function, options? : Options) => {
    // computed和watch需要参数，进行初次触发判断以及是否缓存结果

    // 闭包函数防止污染
    const _effect = () => {
        currentEffect = _effect
        const res = fn()
        return res
    }
    // 将options挂载到_effect上，方便依赖监听触发时判断是否需要执行调度函数
    _effect.options = options
    if (options?.lazy) {
        return _effect
    } else {
        // 立即执行
        _effect()
        return _effect
    }
}

// 依赖收集的map
const depMap = new WeakMap()

// 依赖收集
export const tracker = (target, key) => {
    // 弱引用是否存在对象的依赖集合，不存在则创建
    let dep = depMap.get(target)
    if(!dep) {
        dep = new Map()
        depMap.set(target, dep)
    }
    // map是否存在key的依赖集合，不存在则创建
    let depSet = dep.get(key)
    if(!depSet) {
        depSet = new Set()
        dep.set(key, depSet)
    }
    depSet.add(currentEffect)
}
// 依赖监听触发
export const trigger = (target, key) => {
    const trigger = depMap.get(target)
    if (trigger) {
        const dep = trigger.get(key)
        if (dep) {
            dep.forEach(fn => {
                // 存在调度函数则执行调度函数 会触发响应式数据变化时执行副作用函数 看computed和watch
                if (fn.options?.scheduler) {
                    fn.options.scheduler(fn)
                }else {
                    fn()
                }
            })
        }
    }
}